#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdint.h>
#include <fcntl.h>
#include <glib.h>
#include "logger.h"
#include "hlfs.h"
#include "misc.h"
#include "comm_define.h"
#include "storage.h"
#include "segment_cleaner.h"

int rewrite_alive_blocks_from_seg(struct hlfs_ctrl *ctrl,struct segment_usage *seg_usage){
    g_message("enter func %s\n",__func__);
    int ret = 0;
    gchar * segfile = build_segfile_name(seg_usage->segno);
	bs_file_t file = NULL; 
    if (NULL == (file = ctrl->storage->bs_file_open(ctrl->storage, segfile, BS_READONLY))) {
            g_free(segfile);
			g_message("%s -- open segfile error!\n", __func__);
			return -1;
	}
    char * buff = (char*)g_malloc0(1024llu*1024llu*64llu);
	uint32_t count = ctrl->storage->bs_file_pread(ctrl->storage,file, 
							buff, 1024llu*1024llu*64llu, 0);
    if(count<0){
			ctrl->storage->bs_file_close(ctrl->storage, file);
			g_free(segfile);
			return -1;
	}
    int i= 0;
    uint32_t offset=0;
#if 0
    struct log_header *lh = (struct log_header *)g_malloc0(sizeof(struct log_header));
    if (!lh) {
        g_message("%s -- Allocate Error!\n");
        return -1;
    }
#endif
#if 1
    struct log_header *lh = NULL;
#endif
    g_message("%s -- Before Allocate!\n", __func__);
    g_message("log_num: --> %llu\n", seg_usage->log_num);
    for(i=0;i<seg_usage->log_num;i++){
        lh = (struct log_header*)(buff + offset);
        g_message("log_idx:%d\n", i);
        //      int idx = (seg_usage->log_num -1 )/8 +1;
        int idx = i / 8;
        g_message("bitmap:%hhx\n,bit:%d is %hhx", seg_usage->bitmap[idx],i,seg_usage->bitmap[idx]&(i<<(i%8)));
        if((seg_usage->bitmap[idx] & (1<<(i%8)))){
            g_message("copy! ....... \n");
            g_message("this log[%d]  need move \n",i);
            g_message("lh->start_db_no:%llu, lh->start_db_num: %lu, lh->ib_num: %lu log_size: %lu\n",lh->start_db_no, lh->db_num, lh->ib_num, lh->log_size);
            g_message("+: %lu\n", lh->start_db_no + lh->db_num - 1);
            uint32_t db_start = lh->start_db_no;
            uint32_t db_end = lh->start_db_no + lh->db_num - 1;
            g_message("lh->start_db_no:%lu, lh->end_d: %lu", db_start, db_end);
            g_message(".......................................append begin");
#if 1
            guint32 BLOCKSIZE = ctrl->sb.block_size;
            int expand_size =  (db_end-db_start + 1)*BLOCKSIZE + 
                ib_amount(db_start,db_end) * BLOCKSIZE + 
                LOG_HEADER_LENGTH + 
                sizeof(struct inode) + 
                sizeof(struct inode_map_entry);
            if (expand_size > ctrl->sb.seg_size) {
                g_message("%s -- write length is beyond the limit length!\n", __func__);
                return -1;
            }
            if (ctrl->last_offset + expand_size > ctrl->sb.seg_size) {
                ctrl->last_segno++;
                ctrl->last_offset = 0;
            }
            g_message("%s - last segno:%lld last offset:%llu\n",__func__,ctrl->last_segno,ctrl->last_offset);
#endif
            ret = append_log(ctrl,lh->data,(uint32_t) db_start, (uint32_t) db_end);
            g_message(".......................................append over ret: %lu\n", ret);
            if(-1 == ret) {
                goto out;
            }
        }else{
            g_message("do not need to copy! ....... \n");
        }
        ctrl->last_offset += ret;
        offset += lh->log_size;
    }
out:
    g_free(buff);
    return ret;
}
